home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Sprite 1984 - 1993
/
Sprite 1984 - 1993.iso
/
lib
/
tex
/
inputs
/
tables.sty
< prev
next >
Wrap
Text File
|
1991-05-20
|
21KB
|
602 lines
% modified by Bob Taylor for University of Rochester 20-Mar-87:
% \line macro in Cowan's code is disabled by LaTeX, so I've
% changed all instances of \line in Cowan's code to the new
% definition \tableline as defined right after this comment.
%
\def\tableline{\hbox to \hsize}
%
% +--------------------------------------------------------------------+
% ] ]
% ] TABLES.TEX ]
% ] ]
% ] Ray F. Cowan 15-Feb-85 ]
% ] ]
% ] Princeton University ]
% ] ]
% ] Last Revision: 21-Nov-85 ]
% ] ]
% ] Macros I find handy for making tables. See TABLEDOC TEX for ]
% ] a longer description. The token-counting macros are straight ]
% ] from the TeXbook's "Dirty Tricks" appendix. ]
% ] ]
% +--------------------------------------------------------------------+
%
\newbox\hdbox%
\newcount\hdrows%
\newcount\multispancount%
\newcount\ncase%
\newcount\ncols% This is the number of primary text columns in the table.
\newcount\nrows%
\newcount\nspan%
\newcount\ntemp%
\newdimen\hdsize%
\newdimen\newhdsize%
\newdimen\parasize%
\newdimen\spreadwidth%
\newdimen\thicksize%
\newdimen\thinsize%
\newdimen\tablewidth%
\newif\ifcentertables%
\newif\ifendsize%
\newif\iffirstrow%
\newif\iftableinfo%
\newtoks\dbt%
\newtoks\hdtks%
\newtoks\savetks%
\newtoks\tableLETtokens%
\newtoks\tabletokens%
\newtoks\widthspec%
%
% Book-keeping stuff--see how often these macros are called.
%
%\immediate\write15{%
%CP SMSG GJMSINK TEXTABLE --> TABLE MACROS V. 851121 JOB = \jobname%
%}%
%
% Turn on table diagnostics.
%
\tableinfotrue%
\catcode`\@=11% Allows use of "@" in macro names, like PLAIN.TEX does.
\def\out#1{\immediate\write16{#1}}% Debugging aid. Writes #1 on the
% user's terminal and in the log file.
%
% Define the \tstrut height, depth in terms of the x_height parameter.
%
\def\tstrut{\vrule height3.1ex depth1.2ex width0pt}%
\def\and{\char`\&}% Allows us to get an `&' in the text. This is the
% same as using the PLAIN TeX macro \&.
\def\tablerule{\noalign{\hrule height\thinsize depth0pt}}%
\thicksize=1.5pt% Default thickness for fat rules. The user should feel
% free to change this to his preference.
\thinsize=0.6pt% Default thickness for thin rules.
\def\thickrule{\noalign{\hrule height\thicksize depth0pt}}%
\def\hrulefill{\leaders\hrule\hfill}%
\def\bigrulefill{\leaders\hrule height\thicksize depth0pt \hfill}%
\def\ctr#1{\hfil\ #1\hfil}%
\def\altctr#1{\hfil #1\hfil}%
\def\vctr#1{\hfil\vbox to0pt{\vss\hbox{#1}\vss}\hfil}%
%
% Here are things for controlling the width of the finished table.
%
\tablewidth=-\maxdimen%
\spreadwidth=-\maxdimen%
\def\tabskipglue{0pt plus 1fil minus 1fil}%
%
% Stuff for centering or not.
%
\centertablestrue%
\def\centeredtables{%
\centertablestrue%
}%
\def\noncenteredtables{%
\centertablesfalse%
}%
%
% \vctr vertically centers its argument in the row.
%
\parasize=4in%
\long\def\para#1{% Used to make little paragraphs out of one entry.
{%
\vtop{%
\hsize=\parasize%
\baselineskip14pt%
\lineskip1pt%
\lineskiplimit1pt%
\noindent #1%
\vrule width0pt depth6pt%
}%
}%
}%
%
\gdef\ARGS{########}% Produces the correct number of #'s in the preamble
% by the time eveything is expanded and \halign sees
% it.
\gdef\headerARGS{####}% Same as \ARGS, but used in \header macros.
\def\@mpersand{&}% Allows us to get alignment tab characters later
% when we have made the character "&" an active macro.
{\catcode`\|=13% Make |'s locally active.
\gdef\letbarzero{\let|0}% Globally define a macro that allows us to
% keep active |'s from being expanded in edef's.
\gdef\letbartab{\def|{&&}}%
\gdef\letvbbar{\let\vb|}%
% This \def will cause active |'s read by
% \ruledtable to be converted into double
% alignment tabs.
}% End of locally active |'s.
%
{\catcode`\&=4% Make these alignment tabs.
\def\ampskip{&\omit\hfil&}% This local macro skips a vertical rule.
\catcode`\&=13% Now make &'s into active macros.
\let&0% This allows us to expand \ampskip in the next \xdef without
% attempting to expand the & and getting an "undefined control
% sequence" error.
\xdef\letampskip{\def&{\ampskip}}%
\gdef\letnovbamp{\let\novb&\let\tab&}
% This will cause active &'s read by
% \ruledtable to be converted into
% double tabs and an \omit'ted \vrule.
}% End of locally active &'s.
%
\def\begintable{% Here we make |'s and &'s active characters so we can
% interpret them as macros. Note that this action is
% true only until we encounter the matching \endgroup
% token later at the end of the \ruledtable macro.
\begingroup%
\catcode`\|=13\letbartab\letvbbar%
\catcode`\&=13\letampskip\letnovbamp%
\def\multispan##1{% We must redefine \multispan to count the number
% of primary columns, not physical columns.
\omit \mscount##1%
\multiply\mscount\tw@\advance\mscount\m@ne%
\loop\ifnum\mscount>\@ne \sp@n\repeat%
}% End of \multispan macro.
\def\|{%
&\omit\widevline&%
}%
\ruledtable% Now we call \ruledtable to do the real work.
}% End of \begintable macro.
%
\long\def\ruledtable#1\endtable{%
%
% This macro reads in the user's data entries
% and converts them into a ruled table.
%
% Important note: Many macros and parameters are re-defined here, and
% these must be kept local to the table macros to avoid conflict with
% their use outside of tables. This is done by the \begingroup token
% macro \begintable and the \endgroup token at the end of
% this macro.
%
\offinterlineskip% Needed to make rules touch each other.
\tabskip 0pt% Needed for same reason as \offinterlineskip.
\def\widevline{\vrule width\thicksize}% Make outer \vrule's wider.
\def\endrow{\@mpersand\omit\hfil\crnorm\@mpersand}%
\def\crthick{\@mpersand\crnorm\thickrule\@mpersand}%
\def\crnorule{\@mpersand\crnorm\@mpersand}%
\let\nr=\crnorule% A shorter abbreviation.
\def\endtable{\@mpersand\crnorm\thickrule}%
%
\let\crnorm=\cr% Allows us to use \cr for our own purposes.
%
% Cause user-typed \cr's to follow a row with a \tablerule.
%
\edef\cr{\@mpersand\crnorm\tablerule\@mpersand}%
%
\the\tableLETtokens% Get the user's extra \let's, if any.
%
% Put the data entries into a token register so we can scan through them
% and see what the user is asking us to do.
%
\tabletokens={}% We add an extra alignment tab to the beginning
% of the first row to allow for the first \vrule.
%
% Now count how many rows are in the table and return the result in
% count register \nrows; do the same for columns, and return that
% in register \ncols.
%
\countROWS\tabletokens\into\nrows%
\countCOLS\tabletokens\into\ncols%
%
% Now do a little arithmetic to convert the number of primary columns
% into the number of physical columns that the alignment preamble must
% prepare for; similarly for rows.
%
\advance\ncols by -1%
\divide\ncols by 2%
\advance\nrows by 1%
%
% Tell the user how many rows and columns we found in his data, if he
% wants to know.
%
\iftableinfo %
\immediate\write16{[Nrows=\the\nrows, Ncols=\the\ncols]}%
\fi%
%
% Now we actually go ahead and produce the table.
%
\ifcentertables
\ifhmode \par\fi% Make sure we are in vertical mode.
\tableline{% The final table comes out as an \hbox of width the \hsize.
\hss% The final table will be centered left-to-right.
\else %
\hbox{%
\fi
\vbox{%
\makePREAMBLE{\the\ncols}% Generate the preamble.
\edef\next{\preamble}% This line and the next line force the
\let\preamble=\next% expansion of all \ARGS tokens into the
% appropriate number of #'s.
\makeTABLE{\preamble}{\tabletokens}% Go do the \halign here.
}% End of \vbox.
\ifcentertables \hss}\else }\fi% Finish the centering effect.
% It is important that no spaces
% follow the two `}' here.
% }% End of \tableline
\endgroup% Return all local macros and parameters to their outside
% values.
\tablewidth=-\maxdimen% Reset \tablewidth to normal.
\spreadwidth=-\maxdimen% Same for \spreadwidth.
}% End of macro \ruledtable.
%
\def\makeTABLE#1#2{% Does an \halign for the \ruledtable macro.
{% Start of local parameter values.
%
\let\ifmath0% These macros would cause trouble if they were to be
\let\header0% expanded in the following \xdef; we \let them be
\let\multispan0% equal to a digit, because digits can't be expanded.
%
% Set up the width specification here.
%
\ncase=0%
\ifdim\tablewidth>-\maxdimen \ncase=1\fi%
\ifdim\spreadwidth>-\maxdimen \ncase=2\fi%
\relax% This \relax is absolutely necessary, without it the following
% \ifcase will always take \ncase=0.
%
\ifcase\ncase %
\widthspec={}%
\or %
\widthspec=\expandafter{\expandafter t\expandafter o%
\the\tablewidth}%
\else %
\widthspec=\expandafter{\expandafter s\expandafter p\expandafter r%
\expandafter e\expandafter a\expandafter d%
\the\spreadwidth}%
\fi %
%\out{Widthspec=O\the\widthspecE}%
%\out{Preamble=O\preambleE}%
\xdef\next{% We must force the preamble to be expanded BEFORE the
\halign\the\widthspec{%
% \halign is done; this \edef\next{...}\next construction
% does the trick.
#1% This is the preamble text.
%
\noalign{\hrule height\thicksize depth0pt}% Makes the top \hrule.
%
\the#2\endtable% This is the main body.
%
% \noalign{\hrule height0.7pt depth0pt}% Makes the last \hrule.
}% End of \halign.
}% End of \next.
}% End of local values.
\next% This \next must be outside of the local values, because now
% we want those troublesome macros in the \let's above to have
% their normal actions.
}% End of macro \makeTABLE.
%
\def\makePREAMBLE#1{% This macro generates the necessary preamble for a
% ruled table with #1 primary columns.
% (Primary columns means the number of columns NOT
% counting those used for vertical rules.)
\ncols=#1% Get the number of columns desired.
\begingroup% Start local parameter definitions.
\let\ARGS=0% This is the key to the whole thing; it prevents \ARGS
% from being expanded in the following \edef's.
\edef\xtp{\widevline\ARGS\tabskip\tabskipglue%
&\ctr{\ARGS}\tstrut}% A 1-column preamble. Gets the sizing right.
\advance\ncols by -1% One column has been generated; decrement the
% counter.
\loop% Append as many further columns as needed to the preamble.
\ifnum\ncols>0 %
\advance\ncols by -1%
\edef\xtp{\xtp&\vrule width\thinsize\ARGS&\ctr{\ARGS}}%
\repeat
\xdef\preamble{\xtp&\widevline\ARGS\tabskip0pt%
\crnorm}% Adds the last \vrule.
\endgroup% End of local parameters.
}% End of macro \makePREAMBLE.
%
\def\countROWS#1\into#2{% This counts the number of rows in #1 by
% looking for control sequences that end a row,
% e.g., \cr, \crthick, etc., and puts the result
% into count register #2.
\let\countREGISTER=#2%
\countREGISTER=0%
% \out{In countROWS: tokens are O\the#1E}%
\expandafter\ROWcount\the#1\endcount%
}%
%
\def\ROWcount{%
\afterassignment\subROWcount\let\next= %
}%
\def\subROWcount{%
% \out{In subROWcount: next is O\meaning\nextE}% Debugging aid.
\ifx\next\endcount %
\let\next=\relax%
\else%
\ncase=0%
\ifx\next\cr %
\global\advance\countREGISTER by 1%
\ncase=0%
\fi%
\ifx\next\endrow %
\global\advance\countREGISTER by 1%
\ncase=0%
\fi%
\ifx\next\crthick %
\global\advance\countREGISTER by 1%
\ncase=0%
\fi%
\ifx\next\crnorule %
\global\advance\countREGISTER by 1%
\ncase=0%
\fi%
\ifx\next\header %
% \out{In subROWcount: next=header, ncase set=1}%
\ncase=1%
\fi%
% \out{In subROWcount: ncase is O\the\ncaseE}%
\relax%
\ifcase\ncase %
\let\next\ROWcount%
% \out{subROWcount---> ncase=\the\ncase}%
\or %
\let\next\argROWskip%
% \out{subROWcount---> ncase=\the\ncase}%
\else %
\fi%
\fi%
% \out{subROWcount---> NEXT=\meaning\next}%
\next%
}% End of macro \subROWcount.
%
\def\counthdROWS#1\into#2{%
\dvr{10}%
\let\countREGISTER=#2%
\countREGISTER=0%
\dvr{11}%
% \out{In counthdROWS: tokens are O\the#1E}%
\dvr{13}%
\expandafter\hdROWcount\the#1\endcount%
\dvr{12}%
}%
%
\def\hdROWcount{%
\afterassignment\subhdROWcount\let\next= %
}%
\def\subhdROWcount{%
%\out{In subhdROWcount: next is O\meaning\nextE}%
\ifx\next\endcount %
\let\next=\relax%
\else%
\ncase=0%
\ifx\next\cr %
\global\advance\countREGISTER by 1%
\ncase=0%
\fi%
\ifx\next\endrow %
\global\advance\countREGISTER by 1%
\ncase=0%
\fi%
\ifx\next\crthick %
\global\advance\countREGISTER by 1%
\ncase=0%
\fi%
\ifx\next\crnorule %
\global\advance\countREGISTER by 1%
\ncase=0%
\fi%
\ifx\next\header %
%\out{In subhdROWcount: next=header, ncase set=1}%
\ncase=1%
\fi%
%\out{In subhdROWcount: ncase is O\the\ncaseE}%
\relax%
\ifcase\ncase %
\let\next\hdROWcount%
%\out{subhdROWcount---> ncase=\the\ncase}%
\or%
\let\next\arghdROWskip%
%\out{subhdROWcount---> ncase=\the\ncase}%
\else %
\fi%
\fi%
%\out{subhdROWcount---> NEXT=\meaning\next}%
\next%
}%
%
{\catcode`\|=13\letbartab
\gdef\countCOLS#1\into#2{%
% \out{In countCOLS: tokens are O\the#1E}
\let\countREGISTER=#2%
\global\countREGISTER=0%
\global\multispancount=0%
\global\firstrowtrue
\expandafter\COLcount\the#1\endcount%
\global\advance\countREGISTER by 3%
\global\advance\countREGISTER by -\multispancount
% \out{countCOLS-->O\the\countREGISTERE}
}%
%
\gdef\COLcount{%
\afterassignment\subCOLcount\let\next= %
}%
{\catcode`\&=13%
\gdef\subCOLcount{%
%\out{In subCOLcount: next is O\meaning\nextE}
\ifx\next\endcount %
\let\next=\relax%
\else%
\ncase=0%
\iffirstrow
\ifx\next& %
\global\advance\countREGISTER by 2%
\ncase=0%
\fi%
\ifx\next\span %
\global\advance\countREGISTER by 1%
\ncase=0%
\fi%
\ifx\next| %
\global\advance\countREGISTER by 2%
\ncase=0%
\fi
\ifx\next\|
\global\advance\countREGISTER by 2%
\ncase=0%
\fi
\ifx\next\multispan
\ncase=1%
\global\advance\multispancount by 1%
\fi
\ifx\next\header
\ncase=2%
\fi
\ifx\next\cr \global\firstrowfalse \fi
\ifx\next\endrow \global\firstrowfalse \fi
\ifx\next\crthick \global\firstrowfalse \fi
\ifx\next\crnorule \global\firstrowfalse \fi
\fi% End of \iffirstrow.
\relax%\out{subCOL--> ncase=O\the\ncaseE}
% \out{subCOL--> next=\meaning\next}
\ifcase\ncase %
\let\next\COLcount%
\or %
\let\next\spancount%
\or %
\let\next\argCOLskip%
\else %
\fi %
\fi%
% \out{subCOL--> countREGISTER=O\the\countREGISTERE}
\next%
}%
\gdef\argROWskip#1{%
% Deletes the next balanced, undelimited argument from a
% token list.
% \out{---> Entering argROWskip <---}
% \out{In argROWskip: deleted arg is O#1E}%
\let\next\ROWcount \next%
}% End of macro \argskip.
\gdef\arghdROWskip#1{%
% Deletes the next balanced, undelimited argument from a
% token list.
% \out{---> Entering arghdROWskip <---}
% \out{In arghdROWskip: deleted arg is O#1E}%
\let\next\ROWcount \next%
}% End of macro \arghdROWskip.
\gdef\argCOLskip#1{%
% Deletes the next balanced, undelimited argument from a
% token list.
% \out{---> Entering argCOLskip <---}
% \out{In argCOLskip: deleted arg is O#1E}%
\let\next\COLcount \next%
}% End of macro \argskip.
}% End of active &'s.
}% End of active |'s.
\def\spancount#1{%\out{spancount--->\meaning#1}
\nspan=#1\multiply\nspan by 2\advance\nspan by -1%
\global\advance \countREGISTER by \nspan
% \out{number spancount--->\the\nspan; \the\countREGISTER}
\let\next\COLcount \next}%
%
%\def\dvr#1{\vrule width 1.0pt depth 0pt height 12pt$_{#1}$}
\def\dvr#1{\relax}%
% \omit\hfil%
% \parindent=0pt\hsize=1.1in\valign{%
% \vfil#\vfil&\vfil#\vfil\cr\hfil\hbox{\ Added to\ }\hfil&%
% \hfil\hbox{\ empty events\ }\hfil\cr}\hfil%
\def\header#1{%
\dvr{1}{\let\cr=\@mpersand%
\hdtks={#1}%
%\out{In header: hdtks=O\the\hdtksE}%
\counthdROWS\hdtks\into\hdrows%
\advance\hdrows by 1%
\ifnum\hdrows=0 \hdrows=1 \fi%
%\out{In header: Nhdrows=O\the\hdrowsE}%
\dvr{5}\makehdPREAMBLE{\the\hdrows}%
%\out{In header: headerpreamble=O\headerpreambleE}%
\dvr{6}\getHDdimen{#1}%
%\out{In header: hdsize=O\the\hdsizeE}%
%\striplastCR{#1}%
{\parindent=0pt\hsize=\hdsize{\let\ifmath0%
\xdef\next{\valign{\headerpreamble #1\crnorm}}}\dvr{7}\next\dvr{8}%
}%
}\dvr{2}}% End of macro \header.
%\def\striplastCR#1\cr{\xdef\headerbody{#1}}%
\def\makehdPREAMBLE#1{%This macro generates the necessary preamble for a
\dvr{3}%
% ruled table with \ncols primary columns.
% (Primary columns means the number of columns NOT
% counting those used for vertical rules.
\hdrows=#1% Get the number of columns desired.
{% Start local parameter definitions.
\let\headerARGS=0%
% This is the key to the whole thing; it prevents \ARGS
\let\cr=\crnorm%
% from being expanded in the followin \edef's.
\edef\xtp{\vfil\hfil\hbox{\headerARGS}\hfil\vfil}%
\advance\hdrows by -1% One row has been generated; decrement the
% counter.
\loop% Append as many further rows as needed to the preamble.
\ifnum\hdrows>0%
\advance\hdrows by -1%
\edef\xtp{\xtp&\vfil\hfil\hbox{\headerARGS}\hfil\vfil}%
\repeat%
\xdef\headerpreamble{\xtp\crcr}%
}% End of local parameters.
\dvr{4}}% End of \makehdPREAMBLE.
%
\def\getHDdimen#1{%
%\out{In getHDdimen: Arg 1=O#1E}%
\hdsize=0pt%
\getsize#1\cr\end\cr%
}% End of macro getHDdimen.
\def\getsize#1\cr{%
%\out{In getsize: Arg 1=O#1E}%
% Here we have to check arg#1 and see if the first token in #1 is an
% \end; if so, we stop, else we check the width of arg#1.
% We recall that each arg#1 will be terminated with a \cr token.
\endsizefalse\savetks={#1}%
%\out{In getsize: the savetks = O\the\savetksE}%
\expandafter\lookend\the\savetks\cr%
%\out{In getsize: ifendsize = O\meaning\ifendsizeE}%
\relax \ifendsize \let\next\relax \else%
\setbox\hdbox=\hbox{#1}\newhdsize=1.0\wd\hdbox%
\ifdim\newhdsize>\hdsize \hdsize=\newhdsize \fi%
%\out{In getsize: hdsize=O\the\hdsizeE}%
%\out{In getsize: newhdsize=O\the\newhdsizeE}%
\let\next\getsize \fi%
\next%
}%
\def\lookend{\afterassignment\sublookend\let\looknext= }%
\def\sublookend{\relax%
%\out{In sublookend: looknext = O\looknextE}%
\ifx\looknext\cr %
%\out{In sublooknext: looknext=cr}%
\let\looknext\relax \else %
%\out{In sublooknext: looknext/=cr}%
\relax
\ifx\looknext\end \global\endsizetrue \fi%
\let\looknext=\lookend%
\fi \looknext%
}%
%
% Allow the user to make his own names for crthick, etc.
%
\def\tablelet#1{%
\tableLETtokens=\expandafter{\the\tableLETtokens #1}%
}%
\catcode`\@=12% Change @'s back to their normal category code.
%